package main

import (
	"echo/setting"
	"flag"
	"fmt"
	"net"
	"os"
	"sync"
	"time"

	"github.com/alecthomas/log4go"
	_ "github.com/go-sql-driver/mysql"
)

var fileSetting = flag.String("setting", "conf/settings.json", "file path name of settings")

const logFileName = "flw.log"

var Log4File log4go.Logger

type Recharge_Noti struct {
	Order_Id  string `gorm:"size:255;primary_key"`
	Server_Id string `gorm:"size:4096"`
	Order_Str string `gorm:"size:4096"`
}

// 协议ID
const (
	PROTO_HEARTBEAT = 1
	PROTO_ORDER     = 2
	PROTO_PING      = 3
)

// 连接管理器
type TcpManager struct {
	Orders chan string
	Cons   map[string]net.Conn
	mux    sync.Mutex
}

var TcpMgr TcpManager

func main() {

	TcpMgr.Cons = make(map[string]net.Conn)
	InitConf()
	InitLogger()

	InitTcpService(settings.GetIp(), settings.GetTcpPort())
	Log4File.Close()
}

// 初始化配置
func InitConf() {
	err := settings.Init(*fileSetting)
	if err != nil {
		fmt.Println("fail to read config file ", *fileSetting, err.Error())
		Log4File.Error("fail to read config file ")
		return
	}
}

// 日志记录初始化
func InitLogger() {
	Log4File = log4go.NewLogger()

	flw := log4go.NewFileLogWriter(logFileName, false)
	flw.SetFormat("[%D %T] [%L] (%S) %M")
	flw.SetRotate(true)
	flw.SetRotateSize(0)
	flw.SetRotateLines(0)
	flw.SetRotateDaily(true)
	Log4File.AddFilter("file", log4go.FINE, flw)
}

// 接受所有服务器连接
func InitTcpService(ip, port string) {
	// Listen for incoming connections.
	l, err := net.Listen("tcp", ip+":"+port)
	if err != nil {
		fmt.Println("Error listening:" + err.Error())
		Log4File.Critical("Error listening:" + err.Error())
		os.Exit(1)
	}
	// Close the listener when the application closes.
	defer l.Close()
	fmt.Println("Listening on :" + port)

	for {

		// Listen for an incoming connection.
		conn, err := l.Accept()
		if err != nil {
			fmt.Println("Error accepting: ", err.Error())
			Log4File.Critical("Error accepting: ", err.Error())
			os.Exit(1)
		}
		// Handle connections in a new goroutine.
		//fmt.Println("accept:" + conn.RemoteAddr().String())
		go handleRequest(conn, &TcpMgr)
	}
}

// Handles incoming requests.
func handleRequest(conn net.Conn, tcpMgr *TcpManager) {
	// Make a buffer to hold incoming data.
	buf := make([]byte, 4024)
	// Read the incoming connection into the buffer.
	n, err := conn.Read(buf)
	if err != nil {
		fmt.Println("Error reading:", err.Error())
		Log4File.Warn("Error reading:", err.Error())
		conn.Close()
	} else {
		resp := conn.RemoteAddr().String() + string(buf[:n])
		conn.Write([]byte(resp))
		time.Sleep(time.Duration(500) * time.Millisecond)
		conn.Write([]byte(resp))
		conn.Close()
	}
}
